#include "hrd_logger.h"
#include "hrd_coordinate_list_loader.h"

int16_t HrdCoordinateListLoader_Load(cJSON *coordinate_list_json, struct coordinate_s *coordinate_list, uint8_t max_coordinate_number)
{
#define LOAD_AXIS(axis) \
do { \
    axis ## _list = cJSON_GetObjectItemCaseSensitive(coordinate_list_json, #axis); \
    if (axis ## _list == NULL) { \
        LOG_FATAL("Unable to get " #axis); \
        return LOAD_LIST_FAILURE; \
    } \
} while(0)

#define CHECK_COORDINATE(coord_json) \
do { \
    if (!cJSON_IsNumber(coord_json)) { \
        LOG_FATAL("Not a number occur in coordinates list."); \
        return LOAD_LIST_FAILURE; \
    } \
    if (coord_json->valueint > MAX_COORDINATE || coord_json->valueint < MIN_COORDINATE) { \
        LOG_FATAL("Coordinate %d Not in range %d..%d", coord_json->valueint, MIN_COORDINATE, MAX_COORDINATE); \
        return LOAD_LIST_FAILURE; \
    } \
} while(0)

    uint8_t index = 0;
    uint8_t coordinate_number = 0;
    cJSON *x_list = NULL;
    cJSON *y_list = NULL;
    cJSON *x = NULL;
    cJSON *y = NULL;

    LOAD_AXIS(x);
    LOAD_AXIS(y);

    coordinate_number = cJSON_GetArraySize(x_list);
    if (coordinate_number != cJSON_GetArraySize(y_list)) {
        LOG_FATAL("Length of x and y is not equal.");
        return LOAD_LIST_FAILURE;
    }

    if (coordinate_number > max_coordinate_number) {
        LOG_FATAL("So many coordinates to load MAX %d is supported.", max_coordinate_number);
        return LOAD_LIST_FAILURE;
    }

    index = 0;
    cJSON_ArrayForEach(x, x_list) {
        CHECK_COORDINATE(x);
        coordinate_list[index++].x = x->valueint;
    }
    index = 0;
    cJSON_ArrayForEach(y, y_list) {
        CHECK_COORDINATE(y);
        coordinate_list[index++].y = y->valueint;
    }

    return coordinate_number;
#undef LOAD_AXIS
#undef CHECK_COORDINATE
}